#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "06_lib.h"
static nodep* operater = NULL;
static nodep* parameter = NULL;
static void push(char c);
static int priority(char c);
static int calculate(int op1,int op2,char par);
static int calculateTop(void);
int main(void)
{
	operater = InitStack();
	parameter = InitStack();
	char str[] = "(1+2)*3";
	int len = strlen(str);
	for(int i = 0;i < len;i++)
	{
		push(str[i]);
	}
	int res = 0;
	while(IsEmpty(operater) != 1)
	{
		res = calculateTop();
	}
	printf("%s = %d\n",str,res);
	return 0;
}
static void push(char c)
{
	if(c == ')')
	{
		calculateTop();
		StackPop(operater);
		return;
	}
	else if(isdigit(c) == 0)// 不是数字，统一视作操作符
	{
		int prio = priority(c);
		int topOperaterPrio = priority(ShowTop(operater));	
		// printf("%c = %d\n",c,prio);
		if(prio == -1)// 错误的操作符，退出程序
		{
			printf("incorrect parameter!\n");
			exit(1);
		}
		else if(IsEmpty(operater) == 1 || prio > topOperaterPrio)// 优先级比栈顶元素高或者操作栈为空则入栈
		{
			StackPush(operater,c);
		}
		else if(prio <= topOperaterPrio)
		{
			calculateTop();
			StackPush(operater,c);
		}		
		
	}
	else// 是数字就直接如操作数的栈
	{
		StackPush(parameter,atoi(&c));
	}
}
static int priority(char c)
{
	switch(c)
	{
		case '(':
			return 1;
			break;
		case '+':
		case '-':
			return 2;
			break;
		case '*':
		case '/':
			return 3;
			break;
		default:
			return -1;
			break;
	}
	return -1;
}
int calculate(int op1,int op2,char par)
{
	switch(par)
	{
		case '+':
			return op1 + op2;
			break;
		case '-':
			return op1 - op2;
			break;
		case '*':
			return op1 * op2;
			break;
		case '/':
			return op1 / op2;
			break;
	}
	return 0;
}
static int calculateTop(void)
{
	if(IsEmpty(parameter) == 1)
	{
		printf("incorrect parameter!\n");
		exit(1);	
	}
	int op1 = StackPop(parameter);
	if(IsEmpty(parameter) == 1)
	{
		printf("incorrect parameter!\n");
		exit(1);	
	}
	int op2 = StackPop(parameter);
	//printf("%d %c %d\n",op1,ShowTop(operater),op2);
	op1 = calculate(op1,op2,StackPop(operater));
	StackPush(parameter,op1);
	return op1;
}
